#pragma once
#include "common.h"

namespace anip
{
    /// <summary>
    /// Describes color as coordinates in the CIELAB system (using D50 as white 
    /// point). Note that we *always* use precise colorimetric transforms when
    /// performing conversions, since the 'perceptual' transform intents defined
    /// in ICC files are mostly unsatisfactory for use.
    /// </summary>
    class TrueColor
    {
    private:
        struct Impl;

    public:
        float L, a, b, A;

        constexpr TrueColor() :
            L(0), a(0), b(0), A(0) {}

        TrueColor(const color& srgb);

        constexpr TrueColor(float _L, float _a, float _b, float _A = 1) :
            L(_L), a(_a), b(_b), A(_A) {}

        static void init();
        static void finalize();

        /// <summary>
        /// Returns the color of a blackbody with given temperature in Kelvins, 
        /// useful as a whitepoint. L will be set to 100.
        /// </summary>
        static TrueColor getBlackbodyChromaticities(double temperature);

        static void fromXYZ(const float* xyz, TrueColor& tc);
        static void toXYZ(const TrueColor& tc, const float* xyz);

        static void from_sRGB(const color* rgb, TrueColor* tc, size_t n = 1);
        static void to_sRGB(const TrueColor* tc, color* rgb, size_t n = 1);

        /// <summary>
        /// Checks whether the color is in the sRGB gamut.
        /// </summary>
        bool is_sRGB() const;

        // ANIP_UNDONE: checks if the color is nonexistent
        // bool isImaginary() const;
    };
}

#include "color/trivariate.h"